﻿using System;
using System.ServiceModel.Channels;
using System.Xml;

namespace RockBus.ServiceModel
{
    public class DelegatingHeader : MessageHeader
    {
        // Fields
        private int index;

        private readonly MessageHeaderInfo info;
        private readonly MessageHeaders originalHeaders;

        // Methods
        public DelegatingHeader(MessageHeaderInfo info, MessageHeaders originalHeaders)
        {
            this.info = info;
            this.originalHeaders = originalHeaders;
            this.index = -1;
        }

        private void EnsureIndex()
        {
            if (this.index < 0)
            {
                this.index = this.originalHeaders.FindHeader(this.info.Name, this.info.Namespace);
                if (this.index < 0)
                {
                    throw new InvalidOperationException("Header index");
                }
            }
        }

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            this.EnsureIndex();
            this.originalHeaders.WriteHeaderContents(this.index, writer);
            this.index = -1;
        }

        protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            this.EnsureIndex();
            this.originalHeaders.WriteStartHeader(this.index, writer);
        }

        // Properties
        public override string Actor
        {
            get
            {
                return this.info.Actor;
            }
        }

        public override bool IsReferenceParameter
        {
            get
            {
                return this.info.IsReferenceParameter;
            }
        }

        public override bool MustUnderstand
        {
            get
            {
                return this.info.MustUnderstand;
            }
        }

        public override string Name
        {
            get
            {
                return this.info.Name;
            }
        }

        public override string Namespace
        {
            get
            {
                return this.info.Namespace;
            }
        }

        public override bool Relay
        {
            get
            {
                return base.Relay;
            }
        }
    }
}